package top.whysu.edevice.websocket.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.messaging.simp.config.ChannelRegistration;
import org.springframework.messaging.simp.config.MessageBrokerRegistry;
import org.springframework.web.socket.config.annotation.AbstractWebSocketMessageBrokerConfigurer;
import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker;
import org.springframework.web.socket.config.annotation.StompEndpointRegistry;
import org.springframework.web.socket.server.standard.ServletServerContainerFactoryBean;

/**
 * websocket configuration
 */
@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer {

    private static final int MAX_MESSAGE_SIZE = 20 * 1024;
    private static final long MAX_IDLE = 60 * 60 * 1000;
    @Autowired
    private HttpSessionIdHandshakeInterceptor httpSessionIdHandshakeInterceptor;

    @Autowired
    private PresenceChannelInterceptor presenceChannelInterceptor;

    @Autowired
    private PrincipalDefaultHandshakeHandler principalDefaultHandshakeHandler;

    /**
     * @description: 注册STOMP协议的节点(endpoint)，并映射指定的URL
     * @author: hongyiyong@2018/6/26 9:03
     * @param: [stompEndpointRegistry]
     * @return: void
     * @throws:
     */
    @Override
    public void registerStompEndpoints(StompEndpointRegistry stompEndpointRegistry) {
        stompEndpointRegistry
                //注册一个 /websocket 的 websocket 节点
                .addEndpoint("/websocket")
                //跨越问题
                .setAllowedOrigins("*")
                //添加 websocket处理器
                //.setHandshakeHandler(defaultHandshakeHandler)
                //指定使用SockJS协议
                .withSockJS()
                //添加 websocket拦截器
                .setInterceptors(httpSessionIdHandshakeInterceptor);
                //指定SockJS硬编码资源
                //.setClientLibraryUrl("http://" + IpUtil.getIp() + ":9999/esafe/static/js/sockjs.min.js");
    }

    /**
     * @description: 配置消息代理
     * @author: hongyiyong@2018/6/26 9:03
     * @param: [registry]
     * @return: void
     * @throws:
     */
    @Override
    public void configureMessageBroker(MessageBrokerRegistry registry) {
        //设置客户端接收消息地址的前缀（可不设置）
        //广播消息前缀/topic,点对点消息前缀/queue
        registry.enableSimpleBroker("/topic", "/queue");
        //设置客户端接收点对点消息地址的前缀，默认为 /user
        registry.setUserDestinationPrefix("/queue");
        //设置客户端向服务器发送消息的地址前缀（可不设置）
        registry.setApplicationDestinationPrefixes("/app");
    }

    /**
     * 输出通道参数设置
     */
    @Override
    public void configureClientOutboundChannel(ChannelRegistration registration) {
        registration.taskExecutor()
                //设置消息输入通道的线程池线程数
                .corePoolSize(4)
                //最大线程数
                .maxPoolSize(8)
                //线程活动时间
                .keepAliveSeconds(60);
        //presenceChannelInterceptor 监听websocket链接状态
        registration.setInterceptors(presenceChannelInterceptor);
    }

    /**
     * 输入通道参数设置
     */
    @Override
    public void configureClientInboundChannel(ChannelRegistration registration) {
        registration.taskExecutor()
                //设置消息输入通道的线程池线程数
                .corePoolSize(4)
                //最大线程数
                .maxPoolSize(8)
                //线程活动时间
                .keepAliveSeconds(60);
        //presenceChannelInterceptor 监听websocket链接状态
        registration.setInterceptors(presenceChannelInterceptor);
    }

    @Bean
    public ServletServerContainerFactoryBean createServletServerContainerFactoryBean() {
        ServletServerContainerFactoryBean container = new ServletServerContainerFactoryBean();
        container.setMaxTextMessageBufferSize(MAX_MESSAGE_SIZE);
        container.setMaxBinaryMessageBufferSize(MAX_MESSAGE_SIZE);
        container.setMaxSessionIdleTimeout(MAX_IDLE);
        return container;
    }
}